//
//  JLRouter.swift
//  JLRouter
//
//  Created by Jiang Chencheng on 2024/8/16.
//

import Foundation
import JLCommonKit
import JLLogger
import JLUIKit
import JLRoutes

public enum JLRouter {}

public extension JLRouter {
    typealias RoutableFactory = (_ values: [String: Any]) -> JLRoutable?
    typealias ActableFactory = (_ values: [String: Any]) -> Bool
    
}


extension JLRouter: TypeNameable {}

private extension JLRouter {
    @Late
    static var scheme: String
    static var schemePattern = "\(scheme)://"
}

public extension JLRouter {
    static func register(scheme: String) {
        self.scheme = scheme
    }
    
    static func register(moduleName: String, description: String, factory: @escaping RoutableFactory) {
        let routes = JLRoutes(forScheme: scheme)
        routes.addRoute(moduleName) { parameters in
            let showMode: String = parameters["showMode"] as? String ?? "push"
            guard let vc = factory(parameters) else { return false }
            if showMode == "present" {
                return present(vc)
            } else {
               return push(vc)
            }
        }
        JLLogger.debug("ViewController Registered : \(moduleName) --- Description : \(description)")
    }
    
    static func register(actionName: String, description: String, action: @escaping ActableFactory) {
        let routes = JLRoutes(forScheme: scheme)
        routes.addRoute(actionName) { parameters in
            return action(parameters)
        }
        JLLogger.debug("Action Registered : \(actionName) --- description : \(description)")
    }
}


private extension JLRouter {
    static func push(_ viewController: JLRoutable) -> Bool {
        guard let navigationController = UIViewController.topMost?.navigationController else { return false }
        navigationController.pushViewController(viewController, animated: type(of: viewController).pushAnimated)
        return true
    }
    
    static func present(_ viewController: JLRoutable) -> Bool {
        JLLogger.warning("present viewController cannot support!")
        return false
    }
}

// MARK: - Open

public extension JLRouter {
    static func open(pattern: String) {
        let urlString = schemePattern + pattern
        let url = URL(string: urlString)
        JLRoutes.routeURL(url)
    }
}

// MARK: - Push

public extension JLRouter {
    static func push(pattern: String) {
        let urlString = schemePattern + pattern
        var components = URLComponents(string: urlString)
        var queryItems:[URLQueryItem] = components?.queryItems ?? []
        queryItems.append(URLQueryItem(name: "showMode", value: "push"))
        components?.queryItems = queryItems
        JLRoutes.routeURL(components?.url)
    }
}

// MARK: - Present

public extension JLRouter {
    static func present(pattern: String) {
        let urlString = schemePattern + pattern
        var components = URLComponents(string: urlString)
        var queryItems:[URLQueryItem] = components?.queryItems ?? []
        queryItems.append(URLQueryItem(name: "showMode", value: "push"))
        components?.queryItems = queryItems
        JLRoutes.routeURL(components?.url)
    }
}

// MARK: - Back

public extension JLRouter {
    static func back(animated: Bool = true) {
        guard let navigationController = UIViewController.topMost?.navigationController else { return }
        navigationController.popViewController(animated: animated)
    }
}
 
